同步异步,阻塞与非阻塞!
同步和异步,阻塞和非阻塞是涉及到程序执行和任务处理的概念。
同步(Synchronous):在同步操作中,任务按照顺序依次执行,【每个任务需要等待上一个任务完成后】才能开始执行。即在执行某个任务期间,程序会被阻塞,直到该任务完成。
同步操作通常通过函数调用的方式来实现,函数会一直等待结果返回后再继续执行。
异步(Asynchronous):在异步操作中,任务可以同时进行,【并且不需要等待上一个任务的完成】。在执行某个任务时,程序可以继续执行其他任务,不会被阻塞。
异步操作通常使用回调函数、Promise、async/await等机制来处理,任务在完成后会通过回调或者状态变化来通知程序。
阻塞(Blocking):在阻塞操作中,程序在执行某个任务时会等待任务完成,期间不能执行其他任务。【阻塞操作会使程序暂停执行】,直到该操作完成。
典型的例子是网络请求或者文件读写操作,当程序发起网络请求或者读取文件时,会等待响应或者数据的读取完成,期间程序会处于阻塞状态。
非阻塞(Non-blocking):在非阻塞操作中,程序在执行某个任务时,即使任务尚未完成,也会立即返回并继续执行其他任务。【程序可以通过轮询或者回调等方式来获取任务的完成状态】。
非阻塞操作可以在等待任务完成的同时执行其他任务,从而提高了程序的并发性和响应性。
联系:
同步和异步、阻塞和非阻塞都是描述任务处理方式的概念。
异步操作通常是非阻塞的,因为它们允许程序在等待任务完成期间执行其他操作。
同步操作通常是阻塞的,因为它们要求程序在任务完成前一直等待。
但是,阻塞操作也可以是同步的,例如一个阻塞式函数调用。
非阻塞操作也可以是同步的,就像一个非阻塞式函数调用。
总结起来,同步和异步以及阻塞和非阻塞是相关且互相影响的概念。【同步与异步描述任务的执行方式,阻塞与非阻塞描述任务期间程序的行为】。在实际编程中,根据需求选择适当的方式来处理任务,以提高程序的效率和性能。
首先看一个函数
|
|
func CronRun(CronRefreshChan chan CveCronInfo) { var ticker *time.Ticker ticker = time.NewTicker(time.Minute * 60) defer ticker.Stop() for { select { case <-ticker.C: if GetCve5CronFrequency() > 0 { CronDone() } case info := <-CronRefreshChan: ... } } } |
在Go中,goroutine在函数返回时不会被回收(garbage collected),而是会继续执行直到完成。因此,如果你在CronDone函数中启动了一个子协程,在主协程(即调用CronDone的协程)返回前,子协程仍然可以继续执行。
这意味着,只要主程序的生命周期能够保持运行,CronDone中启动的子协程就有机会正常执行完毕,而不会被垃圾回收。
1,CronDone()执行是否会阻塞for循环?
不会,for循环每次循环就是一个新的函数,CronDone()的执行不会阻塞for循环的继续迭代,而是以异步的方式在后台执行。
错误!!!与是否有返回值无关
- 在 Go 中,函数调用是同步的。当你调用一个函数(如
CronDone())时,程序会等待该函数执行完毕,才会继续执行后面的代码。这意味着如果 CronDone() 是一个耗时的操作,调用它的代码会被阻塞,直到该函数完成。
2,go CronDone的方式是否能阻塞for循环?
不会,相当于开启子协程执行(todo 父子协程声明周期关系需要论证)
3,如果CronDone方法想阻塞for?
可以使用a = CronDone()等待一下返回值就会阻塞,以至于for循环必须等待它。
在Go语言中,如果函数A在其内部调用了函数B,并且在函数B执行完之前,函数A将一直等待。这符合同步(Synchronous)的行为。
根据上述示例,函数A会一直等待函数B执行完毕后才继续执行。请注意,这只适用于同步的函数调用。如果在函数A中使用异步的调用方式(如使用go关键字启动一个新的goroutine来执行函数B),则函数A不会等待函数B完成而继续执行。
在这种情况下,如果一个函数新开了协程A,并且协程A又开了协程B,而协程B中有一个阻塞逻辑会一直执行,那么协程A不会被影响,它将继续独立运行。如果协程A执行完毕并被回收,而协程B仍然在执行,协程B将继续独立运行直到完成,即使协程A已经结束。这说明子协程并非如调用方法一般,存在等待关系,更像是两个完全不相干的协程。当然,主协程与所有子协程息息相关。
「三年博客,如果觉得我的文章对您有用,请帮助本站成长」
共有 0 - golang 协程和函数 同步与异步